export function createConstants(...constants) {
  return constants.reduce((acc, constant) => {
    acc[constant] = constant;
    return acc;
  }, {});
}

export function createReducer(initialState, reducerMap) {
  return (state = initialState, action) => {
    const reducer = reducerMap[action.type];

    return reducer ? reducer(state, action.payload) : state;
  };
}

export function checkHttpStatus(response) {
  if (response.status >= 200 && response.status < 300) {
    return response;
  } else {
    var error = new Error(response.statusText);
    error.response = response;
    throw error;
  }
}

export function parseJSON(response) {
  return response.json();
}

export const arrToObj = (arrdata) => {
  const keysObj = {};
  arrdata.map((item) => {
    const keys = Object.keys(item.goods);
    keys.forEach((item2) => {
      if (keysObj[item2]) {
        const arrItem2 = keysObj[item2].map((item3) => item3.goodsname);
        if (!arrItem2.includes(item.goods[item2].goodsname))
          keysObj[item2].push({
            ...item.goods[item2],
            parentName: item2,
          });
      }

      if (!keysObj[item2])
        keysObj[item2] = [{ ...item.goods[item2], parentName: item2 }];
    });
    return null;
  });
  return keysObj;
};
// 数组扁平化
export const flatArr = (arr) =>
  arr.reduce(
    (fin, nextOne) =>
      fin.concat(nextOne instanceof Array ? flatArr(nextOne) : nextOne),
    []
  );
// 防抖
export const debounce = (func, wait, immediate) => {
  let timeout;

  return function () {
    let context = this;
    let args = arguments;

    if (timeout) clearTimeout(timeout);
    if (immediate) {
      let callNow = !timeout;
      timeout = setTimeout(function () {
        timeout = null;
      }, wait);
      if (callNow) func.apply(context, args);
    } else {
      timeout = setTimeout(function () {
        func.apply(context, args);
      }, wait);
    }
  };
};
// 节流（使用时间戳+定时器实现）
// 使用时间戳
export const throttleOne = (func, wait) => {
  let preTime = 0;

  return function () {
    let nowTime = +new Date();
    let context = this;
    let args = arguments;

    if (nowTime - preTime > wait) {
      func.apply(context, args);
      preTime = nowTime;
    }
  };
};

// 定时器实现
export const throttleTwo = (func, wait) => {
  let timeout;

  return function () {
    let context = this;
    let args = arguments;

    if (!timeout) {
      timeout = setTimeout(function () {
        timeout = null;
        func.apply(context, args);
      }, wait);
    }
  };
};

// 手写reduce
export const myReduce = (cb, initialValue) => {
  const arr = this;
  let final = initialValue || arr[0];
  arr.forEach((item, index, arr) => {
    if (initialValue && index === 0) return;
    final = cb(final, item, index, arr);
  });

  return final;
};

// JS 实现一个带并发限制的异度调度器 Scheduler，保证同时运行的任务最多有两个
class Scheduler {
  constructor(maxLength) {
    // 最大并发数量
    this.maxLength = maxLength;
    this.nowRuningPromiseLength = 0;
    this.waitPromiseMakerList = [];
  }

  add(promiseMaker) {
    if (this.nowRuningPromiseLength < this.maxLength) {
      // 正在运行的promise数量加1
      this.nowRuningPromiseLength++;
      promiseMaker().then(() => {
        this.nowRuningPromiseLength--;
        this.waitPromiseMakerList.length &&
          this.nowRuningPromiseLength < this.maxLength &&
          this.add(this.waitPromiseMakerList.shift());
      });
    } else {
      this.waitPromiseMakerList.push(promiseMaker);
    }
  }
}

const scheduler = new Scheduler(2);
// 最大并发数量2
const addTask = (time, order) => {
  const timeout = (time) => new Promise((resolve) => setTimeout(resolve, time));
  scheduler.add(() => timeout(time).then(() => console.log(order)));
};

addTask(1000, "1");
addTask(500, "2");
addTask(300, "3");
addTask(400, "4");
